-
-
Notifications
You must be signed in to change notification settings - Fork 11.3k
Backends: DX12: Let user specifies the backbuffer count by setting ImGui_ImplDX12_InitInfo::BackBuffer and add support for a single frame in flight. #9035
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: docking
Are you sure you want to change the base?
Conversation
…itInfo::BackBuffer and add support for a single frame in flight
1833948 to
6f07596
Compare
|
With this change the waitable object latency is tied to |
|
Did you check the latency manually? From what I understand, since in D3D12 we explicitly wait for a new frame context to become available before rendering, the number of frames queued for presentation should never exceed the number of frames in flight. Therefore, if the maximum frame latency is set to 2 but there is only 1 frame in flight, you will never queue more than one frame, the maximum frame latency is never reached, and the resulting latency should be identical to having it set to 1. In the opposite case, if there are more frames in flight than back buffers, there still shouldn’t be any difference, since each frame requires a free back buffer to be presented, meaning we can’t present more frames than there are back buffers. SetMaximumFrameLatency is more important for D3D11, where it's the only way to control frames in flight count. In D3D12, however, I believe it's mostly redundant. That said, you’re right: since SetMaximumFrameLatency is conceptually tied to frames in flight, it should be set to the same value for consistency. I’ve fixed it. |
|
Tagging @walbourn since he’s an expert on this topic. If you have a moment, I’d appreciate it if you could check my previous message to make sure I’m not saying anything incorrect, and share your recommendation for the correct SetMaximumFrameLatency value. |
|
Is it typical usage for IMGUI to render directly to the DXGI swapchain for Direct3D scenarios? In most 'professional' render setups, there are generally render-to-texture steps done before it is presented to the swapchain. |
|
Thanks for your quick reply. That’s the approach used in the default ImGui example files for the main viewport, but users are free to render ImGui in any way they prefer. It can absolutely be rendered to a separate texture, but the examples are only meant to demonstrate how to use ImGui and as such, should be kept as simple as possible. This PR is primarily concerned with correct DirectX usage rather than ImGui itself. I have reviewed all the available documentation and resources I could find, but I'm still unsure about the role of SetMaximumFrameLatency when frames in flight (aka one command buffer per frame) are managed manually with fences. |
|
My understanding is that |
|
Note this could well have changed since I last looked at it. This Desktop sample uses it: https://github.com/microsoft/DirectX-Graphics-Samples/blob/master/Samples/Desktop/D3D12nBodyGravity/src/D3D12nBodyGravity.cpp |
Frames in flight can improve and stabilize the framerate, but they may also introduce some input lag, because frames are buffered ahead of time. Allowing the user to set just one frame in flight, effectively disabling frame queuing, can be useful in scenarios where minimizing input latency is more important than maximizing throughput.
Currently, if the user specify only one frame in flight, the DX12 backend crashes. Just to be clear, this is not a regression introduced by #8961, it was already present beforehand.
The crash occurs because, unlike the example implementation, the backend links the back buffer count directly to the number of frames in flight. If you set 1 frame in flight, the backend will use 1 backbuffer, but DXGI_SWAP_EFFECT_FLIP_DISCARD requires at least 2 back buffers, causing the swapchain creation to fail.
To fix this, it was necessary to decouple the back buffer count from the frame in flight count. The back buffer related members have been moved from ImGui_ImplDX12_FrameContext to a new structure, ImGui_ImplDX12_Backbuffer, allowing each to have a different count. I also added a BackBuffer field to ImGui_ImplDX12_InitInfo so users can configure it explicitly.